/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
 */

package controllers

import (
	"encoding/json"
	"prim-server/common"
	"prim-server/errcode"
	"prim-server/logger"
	payService "prim-server/service/pay"
	"prim-server/util"

	"github.com/pkg/errors"
)

const (
	PaymentNotifyURL = "/v1/payment/notify"
	PrePaymentURL    = "/v1/payment/prepay"
	PaymentWebsocket = "/v1/payment/ws"
)

type PaymentController struct {
	CommonController
}

// PaymentNotifyWithWebSocket 和前端建立链接
func (pc *PaymentController) PaymentNotifyWithWebSocket() {
	req := common.OrderReq{}
	if err := json.Unmarshal(pc.Ctx.Input.RequestBody, &req); err != nil {
		logger.Error("PaymentNotifyWithWebSocket Unmarshal error: %v", err)
		pc.HandleErrCode(errcode.E.Base.RequestInvalid.WithErr(err))
		return
	}

	//从缓存中获取订单

	//缓存获取失败从db中获取

	//判断订单是否过期或未处于可支付状态

	//未接入第三方时测试

	//模拟付款时间

	//作为producer往队列中写入信息，为了websocket通知消息

	//根据支付状态修改系统订单状态

	//主动查询数据库
}
func (pc *PaymentController) CheckParameterForPrePay(req common.OrderReq) error {
	if len(req.OrderId) < 1 {
		err := errors.Errorf("订单号长度不合法")
		pc.HandleErrCode(errcode.E.Base.ErrorMessage.WithMessage(err.Error()))
		return err
	}
	if !util.ValidatePaymentMethod(req.PaymentMethod) {
		err := errors.Errorf("请选择支付方式")
		pc.HandleErrCode(errcode.E.Base.ErrorMessage.WithMessage(err.Error()))
		return err
	}
	return nil
}

// PrePay 创建预支付二维码链接
func (pc *PaymentController) PrePay() {
	req := common.OrderReq{}
	if err := json.Unmarshal(pc.Ctx.Input.RequestBody, &req); err != nil {
		logger.Error("PrePay Unmarshal error: %v", err)
		pc.HandleErrCode(errcode.E.Base.RequestInvalid.WithErr(err))
		return
	}
	err := pc.CheckParameterForPrePay(req)
	if err != nil {
		return
	}
	//尝试从缓存中获取订单

	//缓存获取失败从db中获取

	//判断订单是否过期或未处于可支付状态

	prepayInfo := util.PrepayInfo{
		Description:   "自定义数据说明",
		PaymentMethod: req.PaymentMethod,
	}
	//创建订单之后调用预支付,通过NotifyOrderURL接受支付结果通知,ExampleQueryOrderByOutTradeNo
	codeUrl, _ := payService.ExamplePrepay(prepayInfo)
	if err != nil {
		logger.Error(err.Error())
		pc.HandleErrCode(errcode.E.Base.ErrorMessage.WithMessage("第三方支付平台出错"))
		return
	}
	//更新系统订单的第三方平台订单号
	response := common.PaymentInfo{CodeUrl: codeUrl}
	pc.HandleBusinessObj(response)
}

// PaymentNotify 第三方支付通知url--post方法--给第三方平台进行调用
func (pc *PaymentController) PaymentNotify() {
	req := util.OrderNotifyReq{}
	if err := json.Unmarshal(pc.Ctx.Input.RequestBody, &req); err != nil {
		logger.Error("PaymentNotify Unmarshal error: %v", err)
		pc.HandleErrCode(errcode.E.Base.RequestInvalid.WithErr(err))
		return
	}
	transaction, _, err := payService.DecryptFromBody(&req)
	if err != nil {
		pc.HandleErrCode(errcode.E.Base.RequestInvalid.WithErr(err))
		return
	}

	//通知系统第三方订单状态已经修改
	msg := &util.PaymentMessage{
		RecordId:     *transaction.OutTradeNo,
		RecordStatus: *transaction.TradeState,
	}
	payService.WriteIntoMessage(msg.RecordId, msg)
	//系统根据第三方支付状态修改系统订单状态,message[msg.OrderId] = msg
	//修改系统订单,DealWithOrder

	if err != nil {
		logger.Error("DealWithOrder error: %v", err)
		pc.HandleErrCode(errcode.E.Base.RequestInvalid.WithErr(err))
		return
	}
	pc.HandleBusinessSuccess()
}
